#pragma once
#include "Integer.h"

class ResidueField
{
private:
	Integer num;
	Integer mod;
public:
	ResidueField(): num(0), mod(0) {};
	ResidueField(const Integer &n): num(n), mod(0) {};
	ResidueField(const int n): num(n), mod(0) {};
	ResidueField(const unsigned n): num(n), mod(0) {};
	ResidueField(const Integer &n, const Integer &p, bool ok = false);
public:
	const Integer& Value() const
	{
		return this->num;
	}
	const Integer& Modulus() const
	{
		return this->mod;
	}
	std::string str() const;
	friend std::ostream& operator<<(std::ostream &out, const ResidueField &n);
	friend bool IsSameSystem(const ResidueField &m, const ResidueField &n);
	friend bool operator==(const ResidueField &lhs, const ResidueField &rhs);
	friend bool operator!=(const ResidueField &lhs, const ResidueField &rhs);
	friend bool operator<(const ResidueField &lhs, const ResidueField &rhs);
	friend bool operator<=(const ResidueField &lhs, const ResidueField &rhs);
	friend bool operator>(const ResidueField &lhs, const ResidueField &rhs);
	friend bool operator>=(const ResidueField &lhs, const ResidueField &rhs);
	ResidueField operator-() const;
	friend ResidueField Inverse(const ResidueField &n);
	friend ResidueField operator+(const ResidueField &lhs, const ResidueField &rhs);
	ResidueField& operator+=(const ResidueField &addend);
	ResidueField& operator++();
	ResidueField operator++(int);
	friend ResidueField operator-(const ResidueField &lhs, const ResidueField &rhs);
	ResidueField& operator-=(const ResidueField &subtrahend);
	ResidueField& operator--();
	ResidueField operator--(int);
	friend ResidueField operator*(const ResidueField &lhs, const ResidueField &rhs);
	ResidueField& operator*=(const ResidueField &factor);
	friend ResidueField Square(const ResidueField &n);
	friend ResidueField operator/(const ResidueField &lhs, const ResidueField &rhs);
	ResidueField& operator/=(const ResidueField &divisor);
};

